

import skills, movable, directions
from fal.event import EventManager
from utils import Identified
from combatClasses import Attacker, Attackable
from point import Point

class Person(movable.Movable, Attacker, Attackable, skills.Skilled, Identified):
    """
    Base class for all people. Mostly here for type heirarchy and isinstance().
    """
    leftItem = None
    rightItem = None
    hatItem = None
    cape = None
    shoulderItem = None
    hasAuthority = False
    
    def __init__(self, container, initLoc=Point(0.0, 0.0), 
                 initDir=directions.North):
        ##NOTE: If using super with multiple inheritance and more than one
        ## init with arguments, USE ALL KEYWORD ARGUMENTS. You have been
        ## warned.
        super(Person, self).__init__(container=container, initLoc=initLoc,
                                     initDir=initDir)
    
    ##########
    #MOVEMENT  
    def getLength(self, plot):
        """Return, as a percentage less than one, how far plot goes."""
        length = 0.0
        for m in plot:
            length += plot.dist / self.getMaxMove(plot.dir)
        return length
    
    def getMaxMove(self, direction):
        """Return the farthest this boat can go in that direction."""
        return self.speedInfo[self.wind - plot.dir]

    def getAutoMove(self):
        """Return a plot for drifting."""
        raise NotImplementedWarning

    def getPotentialMoves(self):
        """Return the furthest this boat can go in each direction."""
        raise NotImplementedWarning
    
    ##########
    #ATTACKER
    def hasWeapon(self, weapon):
        """
        Returns True if this attacker has that weapon. Allows some
        default code in the base class.
        """
        return weapon == self.leftItem or weapon == self.rightItem
    
    def addWeapon(self, weapon, leftHand=False):
        if isinstance(weapon, weapons.Cannon):
            return False
        if leftHand and self.leftItem is None:
        	self.leftItem = weapon
        elif not leftHand and self.rightItem is None:
        	self.rightItem = weapon
        else:
        	return False
    
    def getObscured(self, target):
        #TODO: Get obscrured info
        #Draw a line from self to target, check for objects in the middle.
        return False
    
    def getDistance(self, target):
        #TODO: Finish getDistance()
        if target in self.container.items.keys():
            self.container.getDistance(self, target)
        else:
            #I honestly have no clue. Think people across two ships.
            return 1
    
    ##########
    #ATTACKABLE
    def parry(self, weapon, damage):
        """
        Used to figure out whether a character parries some weapons' 
        damage. Weapon calls this after figuring out how much damage it
        would deal, if weapon can be parried (pistols, rifles, and cannons
        can't be parried).
        """
        #TODO: Person.parry()
        pass
    
    def takeDamage(self, damage, weapon, dieRoll=None):
        """
        Tells the target how much damage a weapon thinks the target took,
        in addition to the die roll used to determine that.
        """
        if damage['normal'] > 0 or damage['fire'] > 0:
        	self.notifyDeath()
    
